﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using GeckoPhotos.Models;
using GeckoPhotos.Service;
using GeckoPhotos.Repository;
using MvcContrib;
using System.Globalization;
using GeckoPhotos.Auth;

namespace GeckoPhotos.Controllers.Admin
{
    public class UserAdminController : Controller
    {
        /// <summary>
        /// Model used by the Edit actions.
        /// </summary>
        public class EditUserModel
        {
            public EditUserModel()
            {
            }
            public EditUserModel(User user)
            {
                UserID = user.UserID;
                Username = user.Username;
                Password = null;        // Password initially blank; will not be updated if blank when submitted
                DisplayName = user.DisplayName;
                Email = user.Email;
            }
            public int UserID { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
            public string ConfirmPassword { get; set; }
            public string DisplayName { get; set; }
            public string Email { get; set; }
        }

        private readonly UserServiceLayer _userServiceLayer;
        private readonly IMembershipService _membershipService;

        public UserAdminController() :
            this(null, null)
        {
        }

        public UserAdminController(UserServiceLayer userServiceLayer, IMembershipService membershipService)
        {
            _userServiceLayer = userServiceLayer ?? new UserServiceLayer(new EFUserRepository());
            _membershipService = membershipService ?? new AccountMembershipService();
        }

        [HttpGet]
        [Authorize]
        public ActionResult Index()
        {
            IEnumerable<User> users = _userServiceLayer.GetUsers();
            return View(users);
        }

        [HttpGet]
        [Authorize]
        public ActionResult Details(int id)
        {
            User user = _userServiceLayer.GetById(id);
            if (user == null)
                return this.RedirectToAction(c => c.Index());

            return View(user);
        }

        [HttpGet]
        [Authorize]
        public ActionResult Edit(int id)
        {
            User user = _userServiceLayer.GetById(id);
            if (user == null)
                return this.RedirectToAction(c => c.Index());

            return View(new EditUserModel(user));
        }

        [HttpPost]
        [Authorize]
        public ActionResult Edit(EditUserModel model)
        {
            if (!ValidateEdit(model))
            {
                return View(model);
            }

            _userServiceLayer.UpdateUser(model.UserID, model.Username, model.Password, model.DisplayName, model.Email);
            return this.RedirectToAction(c => c.Index());
        }

        private bool ValidateEdit(EditUserModel model)
        {
            if (String.IsNullOrEmpty(model.Username))
            {
                ModelState.AddModelError("username", "You must specify a username.");
            }
            if (String.IsNullOrEmpty(model.DisplayName))
            {
                ModelState.AddModelError("displayName", "You must specify a display name.");
            }
            if (String.IsNullOrEmpty(model.Email))
            {
                ModelState.AddModelError("email", "You must specify an email address.");
            }
            if (!string.IsNullOrEmpty(model.Password))
            {
                if (model.Password.Length < _membershipService.MinPasswordLength)
                {
                    ModelState.AddModelError("password",
                        String.Format(
                            CultureInfo.CurrentCulture,
                             "You must specify a password of {0} or more characters.",
                             _membershipService.MinPasswordLength
                             ));
                }
            }

            if (!String.Equals(model.Password, model.ConfirmPassword, StringComparison.Ordinal))
            {
                ModelState.AddModelError("_FORM", "The new password and confirmation password do not match.");
            }

            return ModelState.IsValid;
        }

    }
}
